package pers.cz.postgirl.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import pers.cz.jefconfig.io.IOUtils;

import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.StringTokenizer;
import java.util.zip.CRC32;

/**
 * @program: postgirl-client
 * @description: 字符串工具类
 * @author: Cheng Zhi
 * @create: 2023-06-09 14:36
 **/
public class StringUtils {

    private static final char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

    /**
     * 计算MD5摘要,
     *
     * @param s
     *            输入
     * @return 32位十六进制数的MD5值
     */
    public final static String getMD5(String s) {
        ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());
        byte[] md = hash(in, "MD5");
        return join(md, (char) 0, 0, md.length);
    }

    public final static String getMD5ByParam(List<Object> list) {

        if (list == null || list.isEmpty()) {
            return "";
        }
        return StringUtils.getMD5(JSON.toJSONString(list, SerializerFeature.IgnoreNonFieldGetter));
    }
    /*
     * 计算消息摘要
     */
    public final static byte[] hash(InputStream in, String algorithm) {
        try {
            MessageDigest mdTemp = MessageDigest.getInstance(algorithm);
            byte[] b = new byte[4096];
            int len = 0;
            while ((len = in.read(b)) != -1) {
                mdTemp.update(b, 0, len);
            }
            return mdTemp.digest();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            closeQuietly(in);
        }
    }

    /**
     * 将数组或列表拼成文本
     *
     * @param b
     * @param dchar
     * @return
     */
    public static String join(byte[] b, char dchar, int offset, int len) {
        if (b == null || b.length == 0)
            return "";
        boolean appendSpace = (dchar != 0);
        int j = offset + len;
        if (j > b.length)
            j = b.length; // 上限
        char str[] = new char[j * ((appendSpace) ? 3 : 2)];
        int k = 0;
        for (int i = offset; i < j; i++) {
            byte byte0 = b[i];
            str[k++] = hexDigits[byte0 >>> 4 & 0xf]; // >>是带符号移位， >>>是无符号移位
            str[k++] = hexDigits[byte0 & 0xf];
            if (appendSpace)
                str[k++] = dchar;
        }
        if (appendSpace) {
            return new String(str, 0, k - 1);
        } else {
            return new String(str);
        }
    }

    public static void closeQuietly(Closeable input) {
        if (input != null) {
            try {
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static String[] split(String strings, String symbol) {
        StringTokenizer st = new StringTokenizer(strings, symbol);
        List<String> tokens = new ArrayList<String>();
        while (st.hasMoreTokens()) {
            String token = st.nextToken();
            token = token.trim();
            tokens.add(token);
        }
        return toStringArray(tokens);
    }

    /**
     * 获取分割完之后的最后一个字符串
     * @param strings
     * @param symbol
     * @return
     */
    public static String getSplitLast(String strings, String symbol) {

        String[] strs = split(strings, symbol);
        int size = strs.length;
        return strs[size-1];
    }

    /**
     * 获取分割之后除去最后一位的其他内容
     * @param strs
     * @param symbol
     * @return
     */
    public static String getSplitNoLast(String strs, String symbol) {
        String[] strings = split(strs, symbol);
        StringBuilder sb = new StringBuilder();
        if (strs.startsWith(symbol)) {
            sb.append(symbol);
        }
        for (int i=0; i<strings.length -1; i++) {
            sb.append(strings[i]);
            sb.append(symbol);
        }

        return sb.toString();
    }
    /**
     * 判断是前缀表达式
     * @param str
     * @return
     */
    public static boolean isPreStr(String str, char ca) {

        char[] chars = str.toCharArray();
        for (char c: chars) {
            if (c == ca) {
                return true;
            } else {
                return false;
            }
        }

        return false;
    }

    public static String[] toStringArray(Collection<String> collection) {
        if (collection == null) {
            return null;
        }
        return collection.toArray(new String[collection.size()]);
    }

    /**
     * 将String转换为Boolean,如果转换不成功，则返回默认类型
     * @param s
     * @param defaultValue
     * @return
     */
    public static Boolean toBoolean(String s, Boolean defaultValue) {

        if ("TRUE".equalsIgnoreCase(s) || "1".equals(s) || "Y".equalsIgnoreCase(s) || "ON".equalsIgnoreCase(s)) {
            return true;
        }

        if ("FALSE".equalsIgnoreCase(s) || "0".equalsIgnoreCase(s) || "N".equalsIgnoreCase(s) || "OFF".equalsIgnoreCase(s)) {
            return false;
        }

        if (defaultValue == null) {
            // 如果不指定默认值，且没有符合上述判断条件的，那么认为这个s不适合转换为Boolean,因此要抛出异常。
            throw new IllegalArgumentException(s + " can not be case to boolean.");
        }

        return defaultValue;
    }

    /**
     * 字符替换
     * @param str
     * @param searchChars
     * @param replaceChars
     * @return
     */
    public static String replaceChars(String str, String searchChars, String replaceChars) {
        if (!isEmpty(str) && !isEmpty(searchChars)) {
            if (replaceChars == null) {
                replaceChars = "";
            }

            boolean modified = false;
            int replaceCharsLength = replaceChars.length();
            int strLength = str.length();
            StringBuilder buf = new StringBuilder(strLength);

            for(int i = 0; i < strLength; ++i) {
                char ch = str.charAt(i);
                int index = searchChars.indexOf(ch);
                if (index >= 0) {
                    modified = true;
                    if (index < replaceCharsLength) {
                        buf.append(replaceChars.charAt(index));
                    }
                } else {
                    buf.append(ch);
                }
            }

            if (modified) {
                return buf.toString();
            } else {
                return str;
            }
        } else {
            return str;
        }
    }

    /**
     * 是否为空
     * @param cs
     * @return
     */
    public static boolean isEmpty(CharSequence cs) {
        return cs == null || cs.length() == 0;
    }

    /**
     * 截取指定字符串中关键字之前的内容
     * @param str
     * @param separator
     * @return
     */
    public static String substringBefore(String str, String separator) {
        if (!isEmpty(str) && separator != null) {
            if (separator.isEmpty()) {
                return "";
            } else {
                int pos = str.indexOf(separator);
                return pos == -1 ? str : str.substring(0, pos);
            }
        } else {
            return str;
        }
    }

    /**
     * 截取指定字符串中关键字之后的内容
     * @param str
     * @param separator
     * @return
     */
    public static String substringAfter(String str, String separator) {
        if (isEmpty(str)) {
            return str;
        } else if (separator == null) {
            return "";
        } else {
            int pos = str.indexOf(separator);
            return pos == -1 ? "" : str.substring(pos + separator.length());
        }
    }

    public static String subStringLast(String str, String separator) {
        if (isEmpty(str)) {
            return str;
        } else if (separator == null) {
            return "";
        } else {
            int pos = str.lastIndexOf(separator);
            return pos == -1 ? "" : str.substring(pos + separator.length());
        }
    }
    /**
     *
     * @param str
     * @param separator
     * @return
     */
    public static String substringAfterLast(String str, String separator) {
        if (isEmpty(str)) {
            return str;
        } else if (isEmpty(separator)) {
            return "";
        } else {
            int pos = str.lastIndexOf(separator);
            return pos != -1 && pos != str.length() - separator.length() ? str.substring(pos + separator.length()) : "";
        }
    }

    /**
     * 计算CRC摘要,8位十六进制数
     */
    public static String getCRC(InputStream in) {
        CRC32 crc32 = new CRC32();
        byte[] b = new byte[65536];
        int len = 0;
        try {
            while ((len = in.read(b)) != -1) {
                crc32.update(b, 0, len);
            }
            return Long.toHexString(crc32.getValue());
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            IOUtils.closeQuietly(in);
        }
    }

    /**
     * 计算CRC摘要,8位十六进制数
     */
    public static String getCRC(String s) {
        ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());
        return getCRC(in);
    }

    /**
     * 将给定单词转化为驼峰命名法
     * @param word
     * @return
     */
    public static String getCamelCase(String word) {

        if (!word.contains("_")) {
            return returnFirstCaps(word);
        }

        String[] s = word.split("_");
        StringBuilder sb = new StringBuilder();
        for (String splitWord : s) {

            sb.append(returnFirstCaps(splitWord));
        }
        return sb.toString();
    }

    public static String getCamelCaseField(String word) {

        if (!word.contains("_")) {
            return word;
        }

        String[] s = word.split("_");
        StringBuilder sb = new StringBuilder();
        int cont = 0;
        for (String splitWord : s) {
            if (cont == 0) {
                sb.append(splitWord);
            } else {
                sb.append(returnFirstCaps(splitWord));
            }
            cont ++;
        }
        return sb.toString();
    }

    /**
     * 将给定单词首字母转化为大写
     * @param word
     * @return
     */
    public static String returnFirstCaps(String word) {

        if (word.length() == 0) {
            return word;
        }

        char[] chars = word.toCharArray();
        char firstLetter = chars[0];
        // 先判断是否属于字母
        if (firstLetter >= 'a' && firstLetter <= 'z') {
            firstLetter = (char) (firstLetter - 32);
        }
        chars[0] = firstLetter;
        StringBuilder sb = new StringBuilder();
        for (char c : chars) {
            sb.append(c);
        }
        return sb.toString();
    }

    public static void main(String[] args) {

        String a = "123!456!789;123;456;789";
        String symbol = ";";
        //System.out.println(substringBefore(a, symbol));
        String[] split = split(a, symbol);
        for (String s : split) {
            System.out.println(s);
        }
    }
}
